package world0;

import java.util.ArrayList;

import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Shape;
import org.newdawn.slick.state.StateBasedGame;

public abstract class Body extends GameObject {
	
	// Attributes
	private float acceleration = 0.0023f; // 0.0020f - Start acceleration(very slow)
	private float maxSpeed = 0.36f; // 0.36f - Start Jump  
	private short maxJump = 80; // 70 - Start jump
	
	private Shape collisionArea;
	private Shape collisionAreaButtom;
	private Shape collisionAreaLeft;
	private Shape collisionAreaRight;
	private Shape collisionAreaTop;
	private Shape collisionAreaSlope;
	
	private ArrayList<LevelObject> solidList;
	private ArrayList<LevelObject> slopeList;
	private ArrayList<Mob> mobList;
	private Player player;
	
	private boolean onFall = true;
	private boolean onJump = false;
	private boolean startJumpSave = false;
	private float startJump;
	
	private final int top = 0;
	private final int left = 1;
	private final int right = 2;
	private final int buttom = 3;
	
	public Body(float x, float y, Image image, int state) {
		super(x, y, image, state);
		
		collisionArea = new Rectangle(x, y, getImageWidth() - 3, getImageHeight() - 2);
		collisionAreaButtom = new Rectangle(x, y, getImageWidth() - 7, 5);
		collisionAreaLeft = new Rectangle(x, y, 5, getImageHeight()- 5);
		collisionAreaRight = new Rectangle(x, y, 5, getImageHeight()- 5);
		collisionAreaTop = new Rectangle(x, y, getImageWidth() - 7, 5);
		collisionAreaSlope = new Rectangle(x, y, 5, 5);
	}

	public abstract void draw(Graphics g);
	
	protected void update(int delta, ArrayList<LevelObject> solidList, ArrayList<LevelObject> slopeList, ArrayList<Mob> mobList, Player player) {
		collisionAreaUpdate();
		
		this.solidList = solidList;
		this.slopeList = slopeList;
		this.mobList = mobList;
		this.player = player;
		
		/* Collision behavior */
		
		/* Move on fall */
		if (onFall) {
			y += maxSpeed * delta;
		}
		
		/* if hit hiting something fall down */
		if (!checkCollisionSide(top) && !onJump) {
			onFall = true;
		}
		
		/* After hitting ground stop fall */
		if (!onJump && checkCollisionSide(buttom) || checkSlope(collisionAreaSlope, slopeList)) {
			onFall = false;
			startJumpSave = false;
		}
		
		
		if(onJump && checkCollisionSide(top)) {
			onFall = true;
			onJump = false;
		}
		
		/* Debug Corner */
		
		if(checkCollisonLevelObjectNonCloud(collisionArea, solidList)) {
			y -= maxSpeed * delta;
		}
		/* Collision behavior END */
	}
	
	private void collisionAreaUpdate() {
		collisionArea.setCenterX(x);
		collisionArea.setCenterY(y);
		
		collisionAreaButtom.setCenterX(x);
		collisionAreaButtom.setCenterY(y + 30);
		
		collisionAreaLeft.setCenterX(x - 14);
		collisionAreaLeft.setCenterY(y);
		
		collisionAreaRight.setCenterX(x + 14);
		collisionAreaRight.setCenterY(y);
		
		collisionAreaTop.setCenterX(x);
		collisionAreaTop.setCenterY(y - 30);
		
		collisionAreaSlope.setCenterX(x);
		collisionAreaSlope.setCenterY(y + 30);
	}
	
	private boolean checkCollisionSide(int side) {
		collisionAreaUpdate();
		boolean collision = false;
		
		if (side == 0) {
			if(checkCollisonLevelObject(collisionAreaTop, solidList, 2))
				collision = true;
		}
		
		if (side == 1) {
			if(checkCollisonLevelObject(collisionAreaLeft, solidList, 2))
				collision = true;
		}
		
		if (side == 2) {
			if(checkCollisonLevelObject(collisionAreaRight, solidList, 2))
				collision = true;
		}
		
		if (side == 3) {
			if(checkCollisonLevelObject(collisionAreaButtom, solidList)) {
				collision = true;
			}
		}
		return collision;
	}

}
